/*
 * Copyright (c) 2008 Benoit Bouchez, Nicolas Giard
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.noocodecommit.wicket.stuff.jquery.plugin.ui.datepicker;

import java.util.Locale;

import org.apache.wicket.markup.html.form.TextField;

import com.noocodecommit.wicket.stuff.jquery.plugin.JQPlugin;
import com.noocodecommit.wicket.stuff.jquery.plugin.JQPluginOptions;

/**
 * 
 * @author Benoit Bouchez
 */
public class JQDatePickerUtils
{

	/**
	 * Create a JQDatePickerBuilder instance on which you can fluently change settings
	 * 
	 * @param id
	 *            wicket component id
	 * @param parent
	 *            parent textfield
	 * @param key
	 *            plugin unique id on which component is attached
	 * @return JQDatePickerBuilder
	 */
	public static JQDatePickerBuilder create(String id, String key, TextField parent)
	{
		return new JQDatePickerBuilder(new JQDatePicker(id, (key == null ? JQDatePickerPlugin.DEFAULT_KEY : key), parent));
	}

	/**
	 * Create a JQDatePickerBuilder instance on which you can fluently change settings
	 * 
	 * @param id
	 *            wicket component id
	 * @param parent
	 *            parent textfield
	 * @return JQDatePickerBuilder
	 */
	public static JQDatePickerBuilder create(String id, TextField parent)
	{
		return new JQDatePickerBuilder(new JQDatePicker(id, null, parent));
	}

	/**
	 * @author Benoit Bouchez
	 */
	public static final class JQDatePickerBuilder
	{
		/** JQuery component */
		private JQDatePicker component;
		/** JQuery default options */
		private JQDatePickerOptions options;

		/**
		 * Constructor
		 * 
		 * @param component
		 *            widget
		 */
		public JQDatePickerBuilder(JQDatePicker component)
		{
			this.component = component;
			this.options = new JQDatePickerOptions();
		}

		/**
		 * Sets plugin init mode
		 * 
		 * @param initMode
		 *            plugin init mode
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder initMode(int initMode)
		{
			component.getPlugin().setInitMode(initMode);
			return this;
		}

		/**
		 * Sets plugin selector when initMode is PLUGIN_INIT_MODE_ONCE
		 * 
		 * @param initOnceSelector
		 *            JQuery selector
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder initOnceSelector(String initOnceSelector)
		{
			component.getPlugin().setInitOnceSelector(initOnceSelector);
			return this;
		}

		/**
		 * Setup a regional for the datepicker This adds lang support .js, so you can setup multiple regional but you can use only one.
		 * 
		 * @param locale
		 *            lang to setup
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder regional(Locale locale)
		{
			component.getPlugin().setRegional(locale);
			return this;
		}

		/**
		 * Sets the clear text option value
		 * 
		 * @param clearText
		 *            datepicker clearText
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder clearText(String clearText)
		{
			options.setClearText(clearText);
			return this;
		}

		/**
		 * Sets the close text option value
		 * 
		 * @param closeText
		 *            datepicker closeText
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder closeText(String closeText)
		{
			options.setCloseText(closeText);
			return this;
		}

		/**
		 * Sets the previous text option value
		 * 
		 * @param prevText
		 *            datepicker prevText
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder prevText(String prevText)
		{
			options.setPrevText(prevText);
			return this;
		}

		/**
		 * Sets the next text option value
		 * 
		 * @param nextText
		 *            datepicker nextText
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder nextText(String nextText)
		{
			options.setNextText(nextText);
			return this;
		}

		/**
		 * Sets the current text option value
		 * 
		 * @param currentText
		 *            datepicker currentText
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder currentText(String currentText)
		{
			options.setCurrentText(currentText);
			return this;
		}

		/**
		 * Sets the clear status option value
		 * 
		 * @param clearStatus
		 *            datepicker clearStatus
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder clearStatus(String clearStatus)
		{
			options.setClearStatus(clearStatus);
			return this;
		}

		/**
		 * Sets the close status option value
		 * 
		 * @param closeStatus
		 *            datepicker closeStatus
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder closeStatus(String closeStatus)
		{
			options.setCloseStatus(closeStatus);
			return this;
		}

		/**
		 * Sets the previous status option value
		 * 
		 * @param prevStatus
		 *            datepicker prevStatus
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder prevStatus(String prevStatus)
		{
			options.setPrevStatus(prevStatus);
			return this;
		}

		/**
		 * Sets the next status option value
		 * 
		 * @param nextStatus
		 *            datepicker nextStatus
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder nextStatus(String nextStatus)
		{
			options.setNextStatus(nextStatus);
			return this;
		}

		/**
		 * Sets the current status option value
		 * 
		 * @param currentStatus
		 *            datepicker currentStatus
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder currentStatus(String currentStatus)
		{
			options.setCurrentStatus(currentStatus);
			return this;
		}

		/**
		 * Sets the month status option value
		 * 
		 * @param monthStatus
		 *            datepicker monthStatus
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder monthStatus(String monthStatus)
		{
			options.setMonthStatus(monthStatus);
			return this;
		}

		/**
		 * Sets the year status option value
		 * 
		 * @param yearStatus
		 *            datepicker yearStatus
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder yearStatus(String yearStatus)
		{
			options.setYearStatus(yearStatus);
			return this;
		}

		/**
		 * Sets the week status option value
		 * 
		 * @param weekStatus
		 *            datepicker weekStatus
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder weekStatus(String weekStatus)
		{
			options.setWeekStatus(weekStatus);
			return this;
		}

		/**
		 * Sets the day status option value
		 * 
		 * @param dayStatus
		 *            datepicker dayStatus
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder dayStatus(String dayStatus)
		{
			options.setDayStatus(dayStatus);
			return this;
		}

		/**
		 * Sets the init status option value
		 * 
		 * @param initStatus
		 *            datepicker initStatus
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder initStatus(String initStatus)
		{
			options.setInitStatus(initStatus);
			return this;
		}

		/**
		 * Sets the date status option value
		 * 
		 * @param dateStatus
		 *            datepicker dateStatus
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder dateStatus(String dateStatus)
		{
			options.setDateStatus(dateStatus);
			return this;
		}

		/**
		 * Sets the day names option value
		 * 
		 * @param dayNames
		 *            datepicker dayNames
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder dayNames(String dayNames)
		{
			options.setDayNames(dayNames);
			return this;
		}

		/**
		 * Sets the short day names option value
		 * 
		 * @param dayNamesShort
		 *            datepicker dayNamesShort
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder dayNamesShort(String dayNamesShort)
		{
			options.setDayNamesShort(dayNamesShort);
			return this;
		}

		/**
		 * Sets the min day names option value
		 * 
		 * @param dayNamesMin
		 *            datepicker dayNamesmin
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder dayNamesMin(String dayNamesMin)
		{
			options.setDayNamesMin(dayNamesMin);
			return this;
		}

		/**
		 * Sets the month names option value
		 * 
		 * @param monthNames
		 *            datepicker monthNames
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder monthNames(String monthNames)
		{
			options.setMonthNames(monthNames);
			return this;
		}

		/**
		 * Sets the short month names option value
		 * 
		 * @param monthNamesShort
		 *            datepicker monthNamesShort
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder monthNamesShort(String monthNamesShort)
		{
			options.setMonthNamesShort(monthNamesShort);
			return this;
		}

		/**
		 * Sets the year range option value
		 * 
		 * @param yearRange
		 *            datepicker yearRange
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder yearRange(String yearRange)
		{
			options.setYearRange(yearRange);
			return this;
		}

		/**
		 * Sets the week header option value
		 * 
		 * @param weekHeader
		 *            datepicker weekHeader
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder weekHeader(String weekHeader)
		{
			options.setWeekHeader(weekHeader);
			return this;
		}

		/**
		 * Sets the range separator option value
		 * 
		 * @param rangeSeparator
		 *            datepicker rangeSeparator
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder rangeSeparator(String rangeSeparator)
		{
			options.setRangeSeparator(rangeSeparator);
			return this;
		}

		/**
		 * Sets the default date option value
		 * 
		 * @param defaultDate
		 *            datepicker defaultDate
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder defaultDate(String defaultDate)
		{
			options.setDefaultDate(defaultDate);
			return this;
		}

		/**
		 * Sets the min date option value
		 * 
		 * @param minDate
		 *            datepicker minDate
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder minDate(String minDate)
		{
			options.setMinDate(minDate);
			return this;
		}

		/**
		 * Sets the max date option value
		 * 
		 * @param maxDate
		 *            datepicker maxDate
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder maxDate(String maxDate)
		{
			options.setMaxDate(maxDate);
			return this;
		}

		/**
		 * Sets the short year cutoff option value
		 * 
		 * @param shortYearCutoff
		 *            datepicker shortYearCutoff
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder shortYearCutoff(String shortYearCutoff)
		{
			options.setShortYearCutoff(shortYearCutoff);
			return this;
		}

		/**
		 * Sets the append text option value
		 * 
		 * @param appendText
		 *            datepicker appendText
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder appendText(String appendText)
		{
			options.setAppendText(appendText);
			return this;
		}

		/**
		 * Sets the show on option value
		 * 
		 * @param showOn
		 *            datepicker showOn
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder showOn(String showOn)
		{
			options.setShowOn(showOn);
			return this;
		}

		/**
		 * Sets the show animation option value
		 * 
		 * @param showAnim
		 *            datepicker showAnim
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder showAnim(String showAnim)
		{
			options.setShowAnim(showAnim);
			return this;
		}

		/**
		 * Sets the show animation settings
		 * 
		 * @param showOptions
		 *            datepicker showOptions
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder showOptions(JQPluginOptions showOptions)
		{
			options.setShowOptions(showOptions);
			return this;
		}

		/**
		 * Sets the button text option value
		 * 
		 * @param buttonText
		 *            datepicker buttonText
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder buttonText(String buttonText)
		{
			options.setButtonText(buttonText);
			return this;
		}

		/**
		 * Sets the button image option value
		 * 
		 * @param buttonImage
		 *            datepicker buttonImage
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder buttonImage(String buttonImage)
		{
			options.setButtonImage(buttonImage);
			return this;
		}

		/**
		 * Sets the alt field option value
		 * 
		 * @param altField
		 *            datepicker altField
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder altField(String altField)
		{
			options.setAltField(altField);
			return this;
		}

		/**
		 * Sets the alt format option value
		 * 
		 * @param altFormat
		 *            datepicker buttonImage
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder altFormat(String altFormat)
		{
			options.setAltFormat(altFormat);
			return this;
		}

		/**
		 * Sets the date format option value
		 * 
		 * @param dateFormat
		 *            datepicker date format
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder dateFormat(String dateFormat)
		{
			options.setDateFormat(dateFormat);
			return this;
		}

		/**
		 * Sets the number of month option value
		 * 
		 * @param numberOfMonths
		 *            datepicker month number
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder numberOfMonths(String numberOfMonths)
		{
			options.setNumberOfMonths(numberOfMonths);
			return this;
		}

		/**
		 * Sets the mandatory option value
		 * 
		 * @param mandatory
		 *            datepicker mandatory
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder mandatory(boolean mandatory)
		{
			options.setMandatory(mandatory);
			return this;
		}

		/**
		 * Sets the close at top option value
		 * 
		 * @param closeAtTop
		 *            datepicker close At Top
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder closeAtTop(boolean closeAtTop)
		{
			options.setCloseAtTop(closeAtTop);
			return this;
		}

		/**
		 * Sets the hideIfNoPrevNext option value
		 * 
		 * @param hideIfNoPrevNext
		 *            datepicker hideIfNoPrevNext
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder hideIfNoPrevNext(boolean hideIfNoPrevNext)
		{
			options.setHideIfNoPrevNext(hideIfNoPrevNext);
			return this;
		}

		/**
		 * Sets the gotoCurrent option value
		 * 
		 * @param gotoCurrent
		 *            datepicker gotoCurrent
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder gotoCurrent(boolean gotoCurrent)
		{
			options.setGotoCurrent(gotoCurrent);
			return this;
		}

		/**
		 * Sets the navigation as date format option value
		 * 
		 * @param navigationAsDateFormat
		 *            datepicker navigationAsDateFormat
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder navigationAsDateFormat(boolean navigationAsDateFormat)
		{
			options.setNavigationAsDateFormat(navigationAsDateFormat);
			return this;
		}

		/**
		 * Sets the change month option value
		 * 
		 * @param changeMonth
		 *            datepicker changeMonth
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder changeMonth(boolean changeMonth)
		{
			options.setChangeMonth(changeMonth);
			return this;
		}

		/**
		 * Sets the change year option value
		 * 
		 * @param changeYear
		 *            datepicker changeYear
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder changeYear(boolean changeYear)
		{
			options.setChangeYear(changeYear);
			return this;
		}

		/**
		 * Sets the change first day option value
		 * 
		 * @param changeFirstDay
		 *            datepicker changeFirstDay
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder changeFirstDay(boolean changeFirstDay)
		{
			options.setChangeFirstDay(changeFirstDay);
			return this;
		}

		/**
		 * Sets the highlight week option value
		 * 
		 * @param highlightWeek
		 *            datepicker highlightWeek
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder highlightWeek(boolean highlightWeek)
		{
			options.setHighlightWeek(highlightWeek);
			return this;
		}

		/**
		 * Sets the RTL option value
		 * 
		 * @param isRTL
		 *            datepicker RTL
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder isRTL(boolean isRTL)
		{
			options.setRTL(isRTL);
			return this;
		}

		/**
		 * Sets the show other month option value
		 * 
		 * @param showOtherMonths
		 *            datepicker showOtherMonths
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder showOtherMonths(boolean showOtherMonths)
		{
			options.setShowOtherMonths(showOtherMonths);
			return this;
		}

		/**
		 * Sets the show status option value
		 * 
		 * @param showStatus
		 *            datepicker showStatus
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder showStatus(boolean showStatus)
		{
			options.setShowStatus(showStatus);
			return this;
		}

		/**
		 * Sets the range select option value
		 * 
		 * @param rangeSelect
		 *            datepicker rangeSelect
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder rangeSelect(boolean rangeSelect)
		{
			options.setRangeSelect(rangeSelect);
			return this;
		}

		/**
		 * Sets the show weeks option value
		 * 
		 * @param showWeeks
		 *            datepicker showWeeks
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder showWeeks(boolean showWeeks)
		{
			options.setShowWeeks(showWeeks);
			return this;
		}

		/**
		 * Sets the button image only option value
		 * 
		 * @param buttonImageOnly
		 *            datepicker buttonImageOnly
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder buttonImageOnly(boolean buttonImageOnly)
		{
			options.setButtonImageOnly(buttonImageOnly);
			return this;
		}

		/**
		 * Sets the first day option value
		 * 
		 * @param firstDay
		 *            datepicker firstDay
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder firstDay(int firstDay)
		{
			options.setFirstDay(firstDay);
			return this;
		}

		/**
		 * Sets the step months option value
		 * 
		 * @param stepMonths
		 *            datepicker stepMonths
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder stepMonths(int stepMonths)
		{
			options.setStepMonths(stepMonths);
			return this;
		}

		/**
		 * Sets the duration option value
		 * 
		 * @param duration
		 *            datepicker duration
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder duration(int duration)
		{
			options.setDuration(duration);
			return this;
		}

		/**
		 * Sets the calculateWeek option value
		 * 
		 * @param calculateWeek
		 *            datepicker calculateWeek
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder calculateWeek(String calculateWeek)
		{
			options.setCalculateWeek(calculateWeek);
			return this;
		}

		/**
		 * Sets the status for date option value
		 * 
		 * @param statusForDate
		 *            datepicker statusForDate
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder statusForDate(String statusForDate)
		{
			options.setStatusForDate(statusForDate);
			return this;
		}

		/**
		 * Sets the beforeShow function
		 * 
		 * @param beforeShowScript
		 *            droppable beforeShow function
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder beforeShowScript(String beforeShowScript)
		{
			options.setBeforeShowScript(beforeShowScript);
			return this;
		}

		/**
		 * Sets the beforeShowDay function
		 * 
		 * @param beforeShowDayScript
		 *            droppable beforeShowDay function
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder beforeShowDayScript(String beforeShowDayScript)
		{
			options.setBeforeShowDayScript(beforeShowDayScript);
			return this;
		}

		/**
		 * Sets the onSelect function
		 * 
		 * @param onSelectScript
		 *            droppable onSelect function
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder onSelectScript(String onSelectScript)
		{
			options.setOnSelectScript(onSelectScript);
			return this;
		}

		/**
		 * Sets the onChangeMonthYear function
		 * 
		 * @param onChangeMonthYearScript
		 *            droppable onChangeMonthYear function
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder onChangeMonthYearScript(String onChangeMonthYearScript)
		{
			options.setOnChangeMonthYearScript(onChangeMonthYearScript);
			return this;
		}

		/**
		 * Sets the onClose function
		 * 
		 * @param onCloseScript
		 *            droppable onClose function
		 * @return JQDatePickerBuilder
		 */
		public JQDatePickerBuilder onCloseScript(String onCloseScript)
		{
			options.setOnCloseScript(onCloseScript);
			return this;
		}

		/**
		 * @return JQDatePicker
		 */
		public JQDatePicker build()
		{
			if (component.getPlugin().getInitMode() == JQPlugin.PLUGIN_INIT_ONCE)
				component.getPlugin().setOptions(options);
			else
				component.setOptions(options);
			return component;
		}
	}
}